﻿#include "DataHandler.h"
#include "HDQt/HDQt.hpp"
#include <mutex>
#include <QCoreApplication>
#include <QDate>
#include <QDebug>
#include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>


static std::once_flag onceFlag;
static DataHandler* handler = nullptr;
DataHandler* DataHandler::getInstance()
{
	std::call_once(onceFlag, [] { handler = new DataHandler; });
    return handler;
}

DataHandler::DataHandler()
	: lock_(QReadWriteLock::Recursive)
{
    readAll();
}

void DataHandler::setDataToday(const Data& data)
{
	QWriteLocker locker(&lock_);  // lock
	QDate date = QDate::currentDate();
	datas_[date.year()][date.month()].insert(date.day(), data);
}

DataHandler::Data DataHandler::getDataToday()
{
	QDate date = QDate::currentDate();
	return getData(date);
}

DataHandler::Data DataHandler::getData(int year, int month, int day)
{
	QReadLocker locker(&lock_);  // lock

	Data data;
	if (month == 0)  // 整年
	{
		for (const auto& mapMonth : datas_.value(year))
		{
			for (const Data& d : mapMonth)
			{
				data += d;
			}
		}
	}
	else
	{
		if (day == 0)  // 整月
		{
			for (const Data& d : datas_.value(year).value(month))
			{
				data += d;
			}
		}
		else  // 当天
		{
			data = datas_.value(year).value(month).value(day);
		}
	}
	return data;
}

void DataHandler::writeAll()
{
	QReadLocker locker(&lock_);  // lock

	QString strFile = QCoreApplication::applicationDirPath() + "/data.json";
	QJsonObject wholeObject;
	for (auto it1 = datas_.cbegin(); it1 != datas_.cend(); ++it1)
	{
		QJsonObject objYear;
		for (auto it2 = it1->cbegin(); it2 != it1->cend(); ++it2)
		{
			QJsonObject objMonth;
			for (auto it3 = it2->cbegin(); it3 != it2->cend(); ++it3)
			{
				QJsonObject objDay;
				objDay.insert("mLeft", it3->mLeft);
				objDay.insert("mRight", it3->mRight);
				objDay.insert("mMid", it3->mMid);
				QJsonObject objKey;
				for (auto it4 = it3->keys.cbegin(); it4 != it3->keys.cend(); ++it4)
					objKey.insert(it4.key(), *it4);
				objDay.insert("keys", objKey);
				objMonth.insert(QString::number(it3.key()), objDay);
			}
			objYear.insert(QString::number(it2.key()), objMonth);
		}
		wholeObject.insert(QString::number(it1.key()), objYear);
	}
	HDQt::writeJson(strFile, wholeObject);
}

void DataHandler::readAll()
{
	QString strFile = QCoreApplication::applicationDirPath() + "/data.json";
	QJsonObject obj;
	HDQt::readJson(strFile, obj);

	QWriteLocker locker(&lock_);  // lock
	datas_.clear();
	for (auto it1 = obj.constBegin(); it1 != obj.constEnd(); ++it1)
	{
		DMap<int, DMap<int, Data>> mapYear;
		QJsonObject objYear = it1->toObject();
		for (auto it2 = objYear.constBegin(); it2 != objYear.constEnd(); ++it2)
		{
			DMap<int, Data> mapMouth;
			QJsonObject objMonth = it2->toObject();
			for (auto it3 = objMonth.constBegin(); it3 != objMonth.constEnd(); ++it3)
			{
				Data data;
				QJsonObject objDay = it3->toObject();
				data.mLeft = objDay.value("mLeft").toInt(0);
				data.mRight = objDay.value("mRight").toInt(0);
				data.mMid = objDay.value("mMid").toInt(0);
				QJsonObject objKey = objDay.value("keys").toObject();
				for (auto it4 = objKey.constBegin(); it4 != objKey.constEnd(); ++it4)
				{
					data.keys.insert(it4.key(), it4->toInt());
				}
				mapMouth.insert(it3.key().toInt(), data);
			}
			mapYear.insert(it2.key().toInt(), mapMouth);
		}
		datas_.insert(it1.key().toInt(), mapYear);
	}
}

DataHandler::~DataHandler()
{
	
}
